---
id: idgenerator
title: 27. 分布式 ID 生成
sidebar_label: 27. 分布式 ID 生成
---

## 27.1 为什么需要分布式 ID

- `全局唯一性`: 不能出现重复的 ID 号, 既然是唯一标识, 这是最基本的要求.

- `趋势递增`: 在 MySQL InnoDB 引擎中使用的是聚集索引, 由于多数 RDBMS 使用 B-tree 的数据结构来存储索引数据, 在主键的选择上面我们应该尽量使用有序的主键保证写入性能.

- `单调递增`: 保证下一个 ID 一定大于上一个 ID, 例如事务版本号, IM 增量消息, 排序等特殊需求.

- `信息安全`: 如果 ID 是连续的, 恶意用户的扒取工作就非常容易做了, 直接按照顺序下载指定 URL 即可; 如果是订单号就更危险了, 竞对可以直接知道我们一天的单量. 所以在一些应用场景下, 会需要 ID 无规则, 不规则.

## 27.2 分布式 ID 有哪些

常见的分布式 ID 有 `连续 GUID`、`短 ID`、`雪花算法 ID`。

## 27.3 如何使用

### 27.3.1 `连续 GUID` 方式

- 静态 `IDGen` 方式

```cs
var guid = IDGen.NextID();

// 还可以配置更多参数
var guid2 = IDGen.NextID(new SequentialGuidSettings { LittleEndianBinary16Format = true }));    // SequentialGuidSettings 参数取决于你的分布式ID的实现
```

:::important 特别提醒

如果在循环中使用 `IDGen` 静态类方式，性能最差，原因是底层不断解析服务。如果非循环中，性能等于下面两种用法。

:::

- `IDistributedIDGenerator` 注入方式 **推荐**

```cs {2,6}
private readonly IDistributedIDGenerator _idGenerator;
public AppServices(IDistributedIDGenerator idGenerator)
{
    _idGenerator = idGenerator;

    var guidObject =  _idGenerator.Create();
}
```

- `SequentialGuidIDGenerator` 方式

```cs
var idGen = new SequentialGuidIDGenerator();
var guid = idGen.Create();

// 更多参数
var idGen2 = new SequentialGuidIDGenerator();
var guid2 = idGen2.Create(new SequentialGuidSettings { LittleEndianBinary16Format = true }));
```

### 27.3.2 短 ID

`短 ID` 按道理不应该放在分布式 ID 生成这个章节，它的作用用途常用于并发不强的内部系统中，比如 `任务ID`，`Issue 编号` 等等。

```cs
var shortid = ShortIDGen.NextID(); // 生成一个包含数字，字母，不包含特殊符号的 8 位短id

// 添加更多配置
var shortid = ShortIDGen.NextID(new GenerationOptions {
    UseNumbers = false, // 不包含数字
    UseSpecialCharacters = true, // 包含特殊符号
    Length = 8，// 设置长度，注意：不设置次长度是随机长度！！！！！！！
});

// 自定义生成短 ID 参与运算字符
string characters = "ⒶⒷⒸⒹⒺⒻⒼⒽⒾⒿⓀⓁⓂⓃⓄⓅⓆⓇⓈⓉⓊⓋⓌⓍⓎⓏⓐⓑⓒⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢⓣⓤⓥⓦⓧⓨⓩ①②③④⑤⑥⑦⑧⑨⑩⑪⑫"; //whatever you want;
ShortIDGen.SetCharacters(characters);

// 自定义随机数（for）步长
int seed = 1939048828;
ShortIDGen.SetSeed(seed);

// 重载所有自定义配置
ShortIDGen.Reset();
```

### 27.3.3 雪花算法 ID

`Furion` 在最新的 `2.1 +` 版本移除了雪花算法 ID 功能，原因是：

**目前，雪花 ID 使用频率不高，而且实现雪花 ID 的方式也是千差万别，所以框架移除该功能，采用拓展或自集成方式。**

## 27.4 反馈与建议

:::note 与我们交流

给 Furion 提 [Issue](https://gitee.com/dotnetchina/Furion/issues/new?issue)。

:::

---
